//
//  G9SDKIAPManager.h
//  NineGameSDK
//
//  Created by michael on 2017/5/16.
//  Copyright © 2017年 NineGame. All rights reserved.
//

#import <Foundation/Foundation.h>

FOUNDATION_EXPORT NSString *kG9SDKIAPManagerErrorDomain;

typedef NS_ENUM(NSUInteger, G9SDKPurchaseState) {
    G9SDKPurchaseStateNone            = 0,
    
    G9SDKPurchaseStateGetProducts     = 10, //获取商品信息
    G9SDKPurchaseStateGetProductSuccess = 9, //获取商品信息成功
    G9SDKPurchaseStateGetProductFailed = 8, // 获取商品信息失败
    
    G9SDKPurchaseStateCreateOrder     = 11, //创建订单
    G9SDKPurchaseStateCreateOrderSuccess = 12, //创建订单成功
    G9SDKPurchaseStateCreateOrderFailed  = 13, //创建订单失败
    
    G9SDKPurchaseStateBeginPurchasing = 21, //开始购买
    G9SDKPurchaseStatePurchasing      = 22, //已加入购买队列，SDK内部不会再有回调
    
    G9SDKPurchaseStateDeferred        = 25, //等待审批(家长控制等)
    G9SDKPurchaseStateFailed          = 26, //购买失败
    G9SDKPurchaseStatePurchased       = 27, //苹果回调购买成功，但还需要校验凭据
    G9SDKPurchaseStateRestored        = 28, //苹果返回Restore
    
    G9SDKPurchaseStateRefreshProduct  = 35, //校验凭证时获取商品信息
    G9SDKPurchaseStateVerifying       = 36, //支付凭据校验
    G9SDKPurchaseStateBizFailed       = 37, //购买失败(凭据校验不通过等)
    
    G9SDKPurchaseStateSuccess         = 40, //购买成功
    
    // AP only，SDK内部不会再有回调
    G9SDKPurchaseStateNoValidTransaction = 101,  ///< Receipt 校验的结果里没有对应有效的交易
    G9SDKPurchaseStateUserNotLogin       = 102,  ///< 用户未登录
    
    // 实名
    G9SDKPurchaseStatecertificating      = 201,     ///<  实名中
    G9SDKPurchaseStateAfterCertification = 202,     ///< 实名制结束
};

typedef NS_ENUM(NSInteger, G9SDKIAPErrorCode) {
    G9SDKIAPErrorCodeCanceled             = 20000000, ///< 操作取消
    
    G9SDKIAPErrorCodeSDKInvalidParam      = 20000001, ///< 参数错误
    G9SDKIAPErrorCodeNotAllowed           = 20000002, ///< 不允许IAP支付，可能是系统设置中开启了【App 内购买项目】的访问限制
    G9SDKIAPErrorCodeSDKNotInitialized    = 20000004, ///< SDK未初始化
    G9SDKIAPErrorCodeProduct              = 20000005, ///< 获取商品信息出错，可能是商品id有误，或者商品在iTunes Connect后台状态错误
    G9SDKIAPErrorCodeReceiptEmpty         = 20000006, ///< 获取不到支付凭证，此时需要刷新凭证，刷新凭证时系统会弹框让用户输入AppleId密码
    G9SDKIAPErrorCodeFrequently           = 20000007, ///< 调用过于频繁
    G9SDKIAPErrorCodeInvalidRspData       = 20000008, ///< 支付中心响应数据错误
    G9SDKIAPErrorCodeDecryptRspData       = 20000009, ///< 解密数据失败
    G9SDKIAPErrorCodeRspInvalidSign       = 20000010, ///< 响应数据签名无效
    G9SDKIAPErrorCodeCryptorFail          = 20000011, ///< 初始化失败，本地秘钥文件解析失败，请检查 keyFilePath 及 appId 是否正确
    G9SDKIAPErrorCodeUnFinishedTransaction = 20000012, ///< 购买的商品含有未结束交易信息

    G9SDKIAPErrorCodeHttpDNSFail          = 20000013,  ///< httpDns错误
    G9SDKIAPErrorCodeIsLimited            = 20000014,  ///< 用户被限额
    G9SDKIAPErrorCodeUnCertification      = 20000015,  ///< 强制实名且实名失败
    G9SDKIAPErrorCodeAfterCertification   = 20000016,  ///< 实名成功，需要用户手动重新购买
};


@class SKProduct, SKProductsRequest, G9SDKOrder, SKPaymentTransaction;

typedef void (^G9SDKProductsRequestSuccessBlock)(NSArray *products, NSArray *invalidProductIdentifiers);
typedef void (^G9SDKProductsRequestFailureBlock)(NSError *error);

typedef void (^G9SDKPurchaseStateUpdateBlock)(G9SDKPurchaseState state);
typedef void (^G9SDKPurchaseSuccessBlock)(G9SDKOrder *order);
typedef void (^G9SDKPurchaseFailureBlock)(NSError *error, SKPaymentTransaction *transaction);

@protocol G9SDKIAPManagerDelegate <NSObject>


/*
 * 支付模块初始化失败
 * @param error 错误信息
 */
- (void)initialIAPManagerFailed:(NSError *)error;


/**
 *  收到服务器校验结果的返回。 当没有 block 处理回调信息的时候会通过这个接口返回服务器验证结果
 *  用户支付成功，但是上传支付结果到 SDK Server 的过程中被打断，下次启动后会继续通过这个回调恢复并继续完成支付流程
 *  G9SDKOrder内部的srcFrom和attachInfo都不会再有值
 *  @param product  用户购买成功的商品
 */
- (void)purchaseDidSuccessWithResult:(G9SDKOrder *)product;

/**
 *  校验流程出错。当没有 block 处理错误信息的时候返回
 *  @param error 错误信息
 */
- (void)purchaseDidFailureWithError:(NSError *)error;

///< 以下两个restore接口，由于没有非消耗性商品的业务，已废弃（SDK不会再有回调），游戏不用再接，已接入的可以删除也可以保留。
/**
 *  restore操作出错
 */
- (void)restoreCompletedTransactionsFailedWithError:(NSError *)error __attribute__((deprecated("暂无回调")));

/**
 * 所有可restore的交易处理完成之后回调，对于每个验证成功的交易，会通过purchaseDidSuccessWithResult回调
 */
- (void)restoreCompletedTransactionsFinished __attribute__((deprecated("暂无回调")));

@end


@interface G9SDKPurchaseInfo : NSObject

@property (nonatomic, copy  ) NSString  *attachInfo; //附加信息，在购买成功后的订单信息以及服务端回调中会原样返回
@property (nonatomic, copy  ) NSString  *orderId;    //订单Id，非必填, 在购买成功后的订单信息以及服务端回调中会原样返回
////支付中心订单验证成功之后会回调此URL通知购买结果, 会优先使用此callback url（如果未设置，则会使用SDK初始化时GameInfo中设置的iapPayCallbackURL）
@property (nonatomic, copy  ) NSString  *iapPayCallbackURL;


#pragma mark - 商品信息，可选参数，当满足 currency 和 orderAmt 同时传入时，支付 SDK 在获取苹果商品信息失败时仍可下单
/// 币种，如 CNY
@property (nonatomic, nonnull , copy) NSString *currency;

/// 订单金额，如 1.00
@property (nonatomic, nonnull , copy) NSString *orderAmt;

/// 商品名称
@property (nonatomic, nonnull , copy) NSString *prdName;


@end

@interface G9SDKIAPManager : NSObject

@property (nonatomic, weak) id<G9SDKIAPManagerDelegate> delegate;

+ (instancetype)sharedManager;

/**
 *  IAP是否支持（访问控制关闭IAP支付时），对应错误码：G9SDKIAPErrorCodeNotAllowed
 */
+ (BOOL)isIAPEnable;

/**
 *  设置是否开启Loading蒙层，防止重复点击，默认开启
 */
@property (nonatomic, assign) BOOL showLoadingHUD;

@end

@interface G9SDKIAPManager (ProductRequest)

/**
 *  通过 product id list 像苹果请求产品列表
 *
 *  @param productIdentifiers 产品 id 的列表，用于向苹果请求具体产品信息
 *  @param success            返回获取到的产品信息列表以及失败的产品id列表
 *  @param failure            错误信息
 *
 */
- (void)requestProductsWithProductIdentifiers:(NSSet *)productIdentifiers
                                      success:(G9SDKProductsRequestSuccessBlock)success
                                      failure:(G9SDKProductsRequestFailureBlock)failure;

@end

@interface G9SDKIAPManager (Payment)

/**
 *  购买商品，在调用此接口时，请确保已经调用过-[G9SDK setRoleInfo:]接口，设置了当前角色信息
 *
 *  @param productIdentifier 需要购买商品的产品 id （product identifier），通过 itunsesconnect 后台配置
 *  @param purchaseInfo      购买参数
 *  @param stateUpdateBlock  购买过程状态变化的回调
 *  @param success           购买成功的回调，返回用户购买的商品。
 *  @param failure           购买失败的回调
 */
- (void)purchaseWithProductIdentifier:(NSString *)productIdentifier
                         purchaseInfo:(G9SDKPurchaseInfo *)purchaseInfo
                          stateUpdate:(G9SDKPurchaseStateUpdateBlock)stateUpdateBlock
                              success:(G9SDKPurchaseSuccessBlock)success
                              failure:(G9SDKPurchaseFailureBlock)failure;


/**
 *  恢复已购买的非消耗性商品，恢复结果会在id<G9SDKIAPManagerDelegate>中回调
 */
- (void)restoreCompletedTransactions __attribute__((deprecated("暂无非消耗性商品，不必调用此函数")));
@end

//============= 内购促销 ================

/// AppStore 内购推广相关回调
@protocol G9SDKPromotedIAPDelegate <NSObject>

/**
 
 当收到系统AppStore商品购买的回调，且用户角色进入游戏时([G9SDK setRoleInfo:]角色进入游戏)，会触发此回调
 收到此回调时，请对当前游戏角色是否满足购买条件等进行检查，若不满足购买条件，请通过toast或弹窗等方式提示用户
 若满足条件，请调用[G9SDKIAPManager appstorePurchaseWithProductId:]
 @param product 要购买的商品
 */
- (void)onPromotedIAPWithProduct:(SKProduct *)product;
@end


@interface G9SDKIAPManager (PromotedIAP)

- (void)setPromotedIAPDelegate:(id<G9SDKPromotedIAPDelegate>)promotedIAPDelegate;

/**
 *  内购推广购买商品
 *
 *  @param productId         需要购买商品的产品 id （product identifier），通过 itunsesconnect 后台配置
 *  @param purchaseInfo      购买参数
 *  @param stateUpdateBlock  购买过程状态变化的回调
 *  @param success           购买成功的回调，返回用户购买的商品。
 *  @param failure           购买失败的回调
 */
- (void)appstorePurchaseWithProductId:(NSString *)productId
                         purchaseInfo:(G9SDKPurchaseInfo *)purchaseInfo
                          stateUpdate:(G9SDKPurchaseStateUpdateBlock)stateUpdateBlock
                              success:(G9SDKPurchaseSuccessBlock)success
                              failure:(G9SDKPurchaseFailureBlock)failure;

@end

@interface G9SDKIAPManager (refreshReceipt)
/**
    【可选】让设备从苹果远程服务器刷新交易凭证，会提示用户输入苹果账号
*/
- (void)refreshReceiptSuccess:(void(^)(void))success failure:(void(^)(NSError *error))failure;

@end
